home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / util / misc / ReportPlus.lha / reportplus / source / f10.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-25  |  34.6 KB  |  1,135 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <intuition/intuition.h>
  4. #include <intuition/gadgetclass.h>
  5. #include <libraries/gadtools.h>
  6. #include <dos/dos.h>
  7. #include <dos/dostags.h>
  8. #include <dos/dosextens.h>
  9. #include <dos/exall.h>
  10. #include <dos/datetime.h>
  11. #include <graphics/gfx.h>
  12.  
  13. #include <clib/alib_protos.h>
  14. #include <clib/intuition_protos.h>
  15. #include <clib/graphics_protos.h>
  16. #include <clib/dos_protos.h>
  17. #include <clib/gadtools_protos.h>
  18. #include <clib/exec_protos.h>
  19.  
  20. #include <ctype.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "rp.h"
  24. #include "files.h"
  25.  
  26. #include <reaction/reaction.h>
  27. #include <gadgets/listbrowser.h>
  28. #include <pragmas/listbrowser_pragmas.h>
  29.  
  30. #define GID_10_LB1 0
  31. #define GIDS_10    GID_10_LB1
  32.  
  33. MODULE void updatefiles(void);
  34. MODULE void stage1(void);
  35. MODULE void files_work(void);                                 // for stage1()
  36. MODULE void stage2(void);
  37. MODULE ABOOL __inline quickcomp(STRPTR first, STRPTR second); // for stage2()
  38. MODULE void dobuffer(ABOOL item, ULONG whichpen);             // for stage2()
  39. MODULE void stage3(void);
  40.  
  41. IMPORT ABOOL                pal, fillwindows;
  42. IMPORT TEXT                 IOBuffer[LONGESTFIELD + 1],
  43.                             aslresult[MEDFIELD + 1];
  44. IMPORT SBYTE                page;
  45. IMPORT ULONG                wbval;
  46. IMPORT struct SharedStruct  shared;
  47. IMPORT struct Screen*       ScreenPtr;
  48. IMPORT struct Library*      ListBrowserBase;
  49. IMPORT struct ExAllData*    EADataPtr;
  50. IMPORT struct VisualInfo*   VisualInfoPtr;
  51. IMPORT struct NewGadget     Gadget;
  52.  
  53. MODULE struct Gadget       *gadgets[GIDS_10 + 1];
  54. MODULE struct List          DirList, EmptyList, FileList, ResultList;
  55. MODULE ABOOL                list_has_nodes = FALSE, stop;
  56. MODULE struct
  57. {   ABOOL show[8];
  58.     TEXT  showlabel[8][17 + 1];
  59.     TEXT  path[VLONGFIELD + 1];
  60.     ULONG entries;
  61. } files =
  62. {   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
  63.     "Very important",
  64.     "Important",
  65.     "Semi-important",
  66.     "Unimportant",
  67.     "Obsolete",
  68.     "3rd-party",
  69.     "Missing",
  70.     "Missing optional",
  71.     "", 0
  72. };
  73. MODULE  BPTR           TheFileHandle       = NULL;
  74. MODULE  UWORD          osversion;
  75. MODULE  TEXT           stringholder1[VLONGFIELD + 1],
  76.                        stringholder2[VLONGFIELD + 1],
  77.                        lockstring[VLONGFIELD + 1];
  78. MODULE  struct Gadget *CY101_OSVersion     = NULL,
  79.                       *TE101_Status        = NULL,
  80.                       *TE101_ShowText      = NULL,
  81.                       *CB101_Show[8] =
  82.                       {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  83.  
  84. #define OSVERSIONS 5 // counting from 0
  85. MODULE  STRPTR OSOptions[OSVERSIONS + 2] =
  86. {   "OS3.1",
  87.     "OS3.5",
  88.     "OS3.5 & Boing Bag(s)",
  89.     "OS3.9",
  90.     "OS3.9 & Genesis Update",
  91.     "OS3.9 & Boing Bag 1",
  92.     NULL
  93. };
  94. MODULE struct
  95. {   ULONG red, green, blue, pennumber;
  96. } penn[7] =
  97. {     {0xFFFFFFFF, 0x22222222, 0x22222222, -1}, // red
  98.       {0xFFFFFFFF, 0x88888888, 0x00000000, -1}, // orange
  99.       {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, -1}, // yellow
  100.       {0x55555555, 0xFFFFFFFF, 0x55555555, -1}, // green
  101.       {0x55555555, 0x55555555, 0xFFFFFFFF, -1}, // blue (obsolete)
  102.       {0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, -1}, // cyan (3rd-party)
  103.       {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -1}  // white (missing)
  104. };
  105.  
  106. // from rp.c
  107. IMPORT SBYTE               page;
  108. IMPORT struct Gadget      *BU99_Right,
  109.                           *ST99_Output,
  110.                           *BU99_OutputASL,
  111.                           *BU99_Update,
  112.                           *BU99_Stop,
  113.                           *CB99_Log,
  114.                           *PrevGadPtr;
  115. IMPORT struct Window*      MainWindowPtr;
  116. IMPORT TEXT                weekdaystring[LEN_DATSTRING],
  117.                            datestring[LEN_DATSTRING],
  118.                            timestring[LEN_DATSTRING];
  119.  
  120. AGLOBAL void files1(void)
  121. {   ULONG i;
  122.  
  123.     clearlblist();
  124.  
  125.     verynewwindow
  126.     (   FILES1WIDTH, FILES1HEIGHT,
  127.         "Report+: System File Report",
  128.         BUTTONIDCMP | STRINGIDCMP | CYCLEIDCMP | CHECKBOXIDCMP
  129.     );
  130.     if (fillwindows)
  131.     {   SetAPen(MainWindowPtr->RPort, 0);
  132.         RectFill(MainWindowPtr->RPort, 446, 20, 446 + 72, 20 + 12);
  133.     }
  134.  
  135.     if (wbval >= 44)
  136.     {   if (!(gadgets[GID_10_LB1] = (struct Gadget *) NewObject(
  137.             LISTBROWSER_GetClass(),   NULL,
  138.             GA_ID,                    GID_10_LB1,
  139.             GA_Left,                  10,
  140.             GA_Top,                   144,
  141.             GA_Width,                 FILES1WIDTH - 20,
  142.             GA_Height,                84,
  143.             GA_ReadOnly,              TRUE,
  144.             GA_TextAttr,              Gadget.ng_TextAttr,
  145.             LISTBROWSER_ScrollRaster, TRUE,
  146.             LISTBROWSER_Labels,       (ULONG) &EmptyList,
  147.             TAG_END)
  148.         ))
  149.         {   rq("Can't create ReAction gadgets!");
  150.         }
  151.  
  152.         AddGList(MainWindowPtr, gadgets[GID_10_LB1], -1, -1, NULL);
  153.         RefreshGList(gadgets[GID_10_LB1], MainWindowPtr, NULL, -1);
  154.     }
  155.  
  156.     setgadget(244, 119, 244, 12, "AmigaOS _Version", PLACETEXT_ABOVE);
  157.     CY101_OSVersion = PrevGadPtr = (struct Gadget *) CreateGadget
  158.     (   CYCLE_KIND,
  159.         PrevGadPtr,
  160.         &Gadget,
  161.         GTCY_Labels, OSOptions,
  162.         GTCY_Active, osversion,
  163.         GT_Underscore, '_',
  164.         TAG_DONE
  165.     );
  166.  
  167.     // show
  168.     setgadget(10, 35, 40, 0, "Show:", PLACETEXT_ABOVE);
  169.     TE101_ShowText = PrevGadPtr = (struct Gadget *) CreateGadget
  170.     (   TEXT_KIND,
  171.         PrevGadPtr,
  172.         &Gadget,
  173.         TAG_DONE
  174.     );
  175.  
  176.     SetDrMd(MainWindowPtr->RPort, JAM2);
  177.     SetAPen(MainWindowPtr->RPort, BLACK);
  178.     for (i = 0; i <= 7; i++)
  179.     {   setgadget(16, 35 + (i * 12), 0, 0, NULL, PLACETEXT_RIGHT);
  180.         Move(MainWindowPtr->RPort, 49, 43 + (i * 12));
  181.         if (i == 7)
  182.         {   SetBPen(MainWindowPtr->RPort, penn[6].pennumber);
  183.         } else
  184.         {   SetBPen(MainWindowPtr->RPort, penn[i].pennumber);
  185.         }
  186.         Text(MainWindowPtr->RPort, files.showlabel[i], strlen(files.showlabel[i]));
  187.         CB101_Show[i] = PrevGadPtr = (struct Gadget *) CreateGadget
  188.         (   CHECKBOX_KIND,
  189.             PrevGadPtr,
  190.             &Gadget,
  191.             GTCB_Checked, files.show[i],
  192.             GT_Underscore, '_',
  193.             TAG_DONE
  194.         );
  195.     }
  196.     SetDrMd(MainWindowPtr->RPort, JAM1);
  197.     Move(MainWindowPtr->RPort, 49 + (8 * 1),  43);
  198.     Text(MainWindowPtr->RPort, "_", 1);
  199.     Move(MainWindowPtr->RPort, 49 + (8 * 0),  55);
  200.     Text(MainWindowPtr->RPort, "_", 1);
  201.     Move(MainWindowPtr->RPort, 49 + (8 * 0),  67);
  202.     Text(MainWindowPtr->RPort, "_", 1);
  203.     Move(MainWindowPtr->RPort, 49 + (8 * 1),  79);
  204.     Text(MainWindowPtr->RPort, "_", 1);
  205.     Move(MainWindowPtr->RPort, 49 + (8 * 1),  91);
  206.     Text(MainWindowPtr->RPort, "_", 1);
  207.     Move(MainWindowPtr->RPort, 49 + (8 * 0), 103);
  208.     Text(MainWindowPtr->RPort, "_", 1);
  209.     Move(MainWindowPtr->RPort, 49 + (8 * 6), 115);
  210.     Text(MainWindowPtr->RPort, "_", 1);
  211.     Move(MainWindowPtr->RPort, 49 + (8 * 9), 127);
  212.     Text(MainWindowPtr->RPort, "_", 1);
  213.  
  214.     /* update */
  215.     setgadget(244, 20, 60, 12, "_Update", NULL);
  216.     BU99_Update = PrevGadPtr = (struct Gadget *) CreateGadget
  217.     (   BUTTON_KIND,
  218.         PrevGadPtr,
  219.         &Gadget,
  220.         GT_Underscore, '_',
  221.         TAG_DONE
  222.     );
  223.     /* stop */
  224.     setgadget(304, 20, 60, 12, "Stop", NULL);
  225.     BU99_Stop = PrevGadPtr = (struct Gadget *) CreateGadget
  226.     (   BUTTON_KIND,
  227.         PrevGadPtr,
  228.         &Gadget,
  229.         GA_Disabled, TRUE,
  230.         TAG_DONE
  231.     );
  232.  
  233.     if (wbval >= 44)
  234.         shared.log = FALSE;
  235.     else shared.log = TRUE;
  236.     // log to file?
  237.     setgadget(244, 45, 0, 0, "_Log to file?", PLACETEXT_RIGHT);
  238.     CB99_Log = PrevGadPtr = (struct Gadget *) CreateGadget
  239.     (   CHECKBOX_KIND,
  240.         PrevGadPtr,
  241.         &Gadget,
  242.         GTCB_Checked, shared.log,
  243.         GT_Underscore, '_',
  244.         TAG_DONE
  245.     );
  246.  
  247.     /* output */
  248.     if (!(shared.output[0]))
  249.         strcpy(shared.output, "RAM:Report.txt");
  250.     setgadget(244, 72, 244, 12, "_Output pathname:", PLACETEXT_ABOVE);
  251.     ST99_Output = PrevGadPtr = (struct Gadget *) CreateGadget
  252.     (   STRING_KIND,
  253.         PrevGadPtr,
  254.         &Gadget,
  255.         GTST_String, &(shared.output),
  256.         GTST_MaxChars, LONGFIELD,
  257.         GA_TabCycle, TRUE,
  258.         GT_Underscore, '_',
  259.         TAG_DONE
  260.     );
  261.     /* output... */
  262.     setgadget(490, 72, 28, 12, "_...", NULL);
  263.     BU99_OutputASL = PrevGadPtr = (struct Gadget *) CreateGadget
  264.     (   BUTTON_KIND,
  265.         PrevGadPtr,
  266.         &Gadget,
  267.         GT_Underscore, '_',
  268.         TAG_DONE
  269.     );
  270.  
  271.     // status
  272.     setgadget(446, 20, 72, 12, "Status:", NULL);
  273.     TE101_Status = PrevGadPtr = (struct Gadget *) CreateGadget
  274.     (   TEXT_KIND,
  275.         PrevGadPtr,
  276.         &Gadget,
  277.         GTTX_Text, "Ready",
  278.         GTTX_Border, TRUE,
  279.         TAG_DONE
  280.     );
  281.  
  282.     drawgadgets((UWORD) ~0);
  283.  
  284.     if (wbval < 44)
  285.     {   GT_SetGadgetAttrs
  286.         (   CB99_Log,
  287.             MainWindowPtr, NULL,
  288.             GA_Disabled, TRUE,
  289.             TAG_DONE
  290.         );
  291.     }
  292.     if (!shared.log)
  293.     {   GT_SetGadgetAttrs
  294.         (   ST99_Output,
  295.             MainWindowPtr, NULL,
  296.             GA_Disabled, TRUE,
  297.             TAG_DONE
  298.         );
  299.         GT_SetGadgetAttrs
  300.         (   BU99_OutputASL,
  301.             MainWindowPtr, NULL,
  302.             GA_Disabled, TRUE,
  303.             TAG_DONE
  304.         );
  305.     }
  306.     loop();
  307.     clearlblist();
  308.     closewindow();
  309. }
  310.  
  311. MODULE void updatefiles(void)
  312. {   ULONG            i;
  313.  
  314.     /* Gadgets are: BU99_Right ('menu')
  315.                     BU99_Update
  316.                     CB99_Log, ST99_Output, BU99_OutputASL
  317.                     CY101_OSVersion
  318.                     CB101_Show[]
  319.     All are ghosted during operation. Then their ghosting status returns
  320.     to normal (not necessarily unghosted).
  321.  
  322.     Disable the `Menu' (BU), `Update' (BU). `Log to file?' (CB),
  323.     `Pathname' (ST), `...' (BU), `Show' (CB), `OS version' (MX), `Stop'
  324.     (BU) gadgets. Status (TE) is changed.
  325.  
  326.         0: Gadget handling.
  327.         1: Set up lists, do the directory examination.
  328.            (For each `source' directory in the `queue', before doing it
  329.            we check for a break. `Break opportunity 1'.)
  330.     At this point we have an empty DirList, and a full FileList, and an
  331.     empty ResultList.
  332.         2: Create the ResultList.
  333.            (For each `source' file in the `queue', before doing it we
  334.            check for a break. `Break opportunity 2'.)
  335.         3: Show results.
  336.  
  337.        DirList: an Exec list of directories found, awaiting examination.
  338.       FileList: an Exec list of files found, awaiting processing.
  339.     ResultList: a listbrowser list of files found, for display. */
  340.  
  341.     strcpy
  342.     (   shared.output,
  343.         ((struct StringInfo *) ST99_Output->SpecialInfo)->Buffer
  344.     );
  345.  
  346.     stop = FALSE;
  347.     GT_SetGadgetAttrs
  348.     (   BU99_Right,
  349.         MainWindowPtr, NULL,
  350.         GA_Disabled, TRUE,
  351.         TAG_DONE
  352.     );
  353.     GT_SetGadgetAttrs
  354.     (   BU99_Update,
  355.         MainWindowPtr, NULL,
  356.         GA_Disabled, TRUE,
  357.         TAG_DONE
  358.     );
  359.     GT_SetGadgetAttrs
  360.     (   CB99_Log,
  361.         MainWindowPtr, NULL,
  362.         GA_Disabled, TRUE,
  363.         TAG_DONE
  364.     );
  365.     GT_SetGadgetAttrs
  366.     (   ST99_Output,
  367.         MainWindowPtr, NULL,
  368.         GA_Disabled, TRUE,
  369.         TAG_DONE
  370.     );
  371.     GT_SetGadgetAttrs
  372.     (   BU99_OutputASL,
  373.         MainWindowPtr, NULL,
  374.         GA_Disabled, TRUE,
  375.         TAG_DONE
  376.     );
  377.     GT_SetGadgetAttrs
  378.     (   CY101_OSVersion,
  379.         MainWindowPtr, NULL,
  380.         GA_Disabled, TRUE,
  381.         TAG_DONE
  382.     );
  383.     for (i = 0; i <= 7; i++)
  384.     {   GT_SetGadgetAttrs
  385.         (   CB101_Show[i],
  386.             MainWindowPtr, NULL,
  387.             GA_Disabled, TRUE,
  388.             TAG_DONE
  389.         );
  390.     }
  391.     GT_SetGadgetAttrs
  392.     (   BU99_Stop,
  393.         MainWindowPtr, NULL,
  394.         GA_Disabled, FALSE,
  395.         TAG_DONE
  396.     );
  397.     GT_SetGadgetAttrs
  398.     (   TE101_Status,
  399.         MainWindowPtr, NULL,
  400.         GTTX_Text, "Busy",
  401.         TAG_DONE
  402.     );
  403.  
  404.     SetGadgetAttrs
  405.     (   gadgets[GID_10_LB1], MainWindowPtr, NULL,
  406.         LISTBROWSER_Labels, NULL,
  407.         TAG_END
  408.     );
  409.     SetGadgetAttrs
  410.     (   gadgets[GID_10_LB1], MainWindowPtr, NULL,
  411.         LISTBROWSER_Labels, (ULONG) &EmptyList,
  412.         TAG_END
  413.     );
  414.     clearlblist();
  415.  
  416.     stage1();
  417.     if (!stop)
  418.     {   stage2();
  419.     }
  420.     FreeNameNodes(&FileList);
  421.     if (!stop)
  422.     {   stage3();
  423.     }
  424.  
  425.     GT_SetGadgetAttrs
  426.     (   BU99_Right,
  427.         MainWindowPtr, NULL,
  428.         GA_Disabled, FALSE,
  429.         TAG_DONE
  430.     );
  431.     GT_SetGadgetAttrs
  432.     (   BU99_Update,
  433.         MainWindowPtr, NULL,
  434.         GA_Disabled, FALSE,
  435.         TAG_DONE
  436.     );
  437.     if (wbval >= 44)
  438.     {   GT_SetGadgetAttrs
  439.         (   CB99_Log,
  440.             MainWindowPtr, NULL,
  441.             GA_Disabled, FALSE,
  442.             TAG_DONE
  443.         );
  444.     }
  445.     if (shared.log)
  446.     {   GT_SetGadgetAttrs
  447.         (   ST99_Output,
  448.             MainWindowPtr, NULL,
  449.             GA_Disabled, FALSE,
  450.             TAG_DONE
  451.         );
  452.         GT_SetGadgetAttrs
  453.         (   BU99_OutputASL,
  454.             MainWindowPtr, NULL,
  455.             GA_Disabled, FALSE,
  456.             TAG_DONE
  457.         );
  458.     }
  459.     GT_SetGadgetAttrs
  460.     (   CY101_OSVersion,
  461.         MainWindowPtr, NULL,
  462.         GA_Disabled, FALSE,
  463.         TAG_DONE
  464.     );
  465.     for (i = 0; i <= 7; i++)
  466.     {   GT_SetGadgetAttrs
  467.         (   CB101_Show[i],
  468.             MainWindowPtr, NULL,
  469.             GA_Disabled, FALSE,
  470.             TAG_DONE
  471.         );
  472.     }
  473.     GT_SetGadgetAttrs
  474.     (   BU99_Stop,
  475.         MainWindowPtr, NULL,
  476.         GA_Disabled, TRUE,
  477.         TAG_DONE
  478.     );
  479.     GT_SetGadgetAttrs
  480.     (   TE101_Status,
  481.         MainWindowPtr, NULL,
  482.         GTTX_Text, "Ready",
  483.         TAG_DONE
  484.     );
  485. }
  486.  
  487. MODULE void stage1(void)
  488. {   struct NameNode* NodePtr;
  489.  
  490.     NewList(&FileList);
  491.     NewList(&DirList);
  492.     NewList(&ResultList);
  493.     AddNameToTail(&DirList, "");
  494.     // pop all the directories from the work stack, and send them one
  495.     // at a time to files_work() for processing.
  496.     while ((DirList.lh_Head)->ln_Succ) // while the list is non-empty
  497.     {   if (checkbreak() == 1) // we don't yet support completely quitting
  498.         {   stop = TRUE;
  499.             GT_SetGadgetAttrs
  500.             (   TE101_Status,
  501.                 MainWindowPtr, NULL,
  502.                 GTTX_Text, "Stopping",
  503.                 TAG_DONE
  504.             );
  505.             GT_SetGadgetAttrs
  506.             (   BU99_Stop,
  507.                 MainWindowPtr, NULL,
  508.                 GA_Disabled, TRUE,
  509.                 TAG_DONE
  510.             );
  511.             break;
  512.         }
  513.  
  514.         /* remove the dir-node from the list, copy its path to
  515.            stringholder1, call files_work, then free the dir-node. */
  516.  
  517.         if (!(NodePtr = (struct NameNode *) RemTail(&DirList)))
  518.         {   rq("RemTail() failed (list is empty!)"); // this should never happen
  519.         }
  520.         strcpy(stringholder1, NodePtr->nn_Data);
  521.         files_work();
  522.         FreeMem(NodePtr, sizeof(struct NameNode));
  523.     }
  524.     FreeNameNodes(&DirList); // Not required unless stopping early (although harmless).
  525. }
  526.  
  527. MODULE void stage2(void)
  528. {   ABOOL            matched, infomatched;
  529.     ULONG            i, length;
  530.     UBYTE            theversion;
  531.     struct NameNode* NodePtr;
  532.  
  533.     // Everything is already allocated. Don't deallocate in this routine.
  534.  
  535.     if (shared.log)
  536.     {   if (!(TheFileHandle = (BPTR) Open(shared.output, MODE_READWRITE)))
  537.             rq("Can't open file for appending!");
  538.         Seek(TheFileHandle, 0, OFFSET_END);
  539.     }
  540.  
  541.     // Now we have the list of files
  542.     getdate();
  543.     strcpy(IOBuffer, "AmigaOS 3.");
  544.     if (osversion == 0)
  545.     {   theversion = 31;
  546.         strcat(IOBuffer, "1");
  547.     } elif (osversion == 1)
  548.     {   theversion = 35;
  549.         strcat(IOBuffer, "5");
  550.     } elif (osversion == 2)
  551.     {   theversion = 36;
  552.         strcat(IOBuffer, "5 + BB1/2");
  553.     } elif (osversion == 3)
  554.     {   theversion = 39;
  555.         strcat(IOBuffer, "9");
  556.     } elif (osversion == 5)
  557.     {   theversion = 41;
  558.         strcat(IOBuffer, "9 + BB1");
  559.     } else
  560.     {   // assert(osversion == 4);
  561.         theversion = 40;
  562.         strcat(IOBuffer, "9 + Genesis Update");
  563.     }
  564.     strcat(IOBuffer, " system files at ");
  565.     strcat(IOBuffer, timestring);
  566.     strcat(IOBuffer, " on ");
  567.     strcat(IOBuffer, weekdaystring);
  568.     strcat(IOBuffer, " ");
  569.     strcat(IOBuffer, datestring);
  570.     strcat(IOBuffer, ":\n"); // another \n is inserted automatically by dobuffer()
  571.     dobuffer(FALSE, 0);
  572.  
  573.     for (i = 0; i <= FILES; i++)
  574.         os[i].matched = os[i].infomatched = FALSE;
  575.  
  576.     // stop is always FALSE at this point, because this function is not
  577.     // called otherwise.
  578.  
  579.     while ((FileList.lh_Head)->ln_Succ) // while the list is non-empty
  580.     {   if (checkbreak() == 1)
  581.         {   stop = TRUE;
  582.             GT_SetGadgetAttrs
  583.             (   TE101_Status,
  584.                 MainWindowPtr, NULL,
  585.                 GTTX_Text, "Stopping",
  586.                 TAG_DONE
  587.             );
  588.             GT_SetGadgetAttrs
  589.             (   BU99_Stop,
  590.                 MainWindowPtr, NULL,
  591.                 GA_Disabled, TRUE,
  592.                 TAG_DONE
  593.             );
  594.             strcpy(IOBuffer, "Aborted by user!");
  595.             dobuffer(FALSE, 0);
  596.             break;
  597.         }
  598.         // assert(!stop);
  599.  
  600.         if (!(NodePtr = (struct NameNode *) RemTail(&FileList)))
  601.         {   rq("RemTail() failed (list is empty!)"); // should never happen
  602.         }
  603.         strcpy(stringholder1, NodePtr->nn_Data);
  604.         length = strlen(stringholder1);
  605.         FreeMem(NodePtr, sizeof(struct NameNode));
  606.  
  607.         // now we have removed the file from the `queue', and copied its
  608.         // name into stringholder1. Now we check it against each system
  609.         // file.
  610.  
  611.         matched = infomatched = FALSE;
  612.         for (i = 0; i <= FILES; i++)
  613.         {   if (os[i].version <= theversion)
  614.             {   if (!matched && quickcomp(stringholder1, os[i].pathname))
  615.                 {   // we have a match
  616.  
  617.                     strcpy(IOBuffer, os[i].pathname);
  618.                     matched = os[i].matched = TRUE;
  619.  
  620.                     // check whether file is obsoleted by OS3.9 or by Genesis Update
  621.                     if
  622.                     (   (theversion >= 39 && (os[i].flags & NOT39))
  623.                      || (theversion >= 40 && (os[i].flags & NOT39UPDATE))
  624.                      || (os[i].flags & CODE_BLUE)
  625.                     )
  626.                     {   dobuffer(TRUE, 12);
  627.                     } elif (os[i].flags & CODE_RED)
  628.                     {   dobuffer(TRUE,  8);
  629.                     } elif (os[i].flags & CODE_ORANGE)
  630.                     {   dobuffer(TRUE,  9);
  631.                     } elif (os[i].flags & CODE_YELLOW)
  632.                     {   dobuffer(TRUE, 10);
  633.                     } else
  634.                     {   // assert(os[i].flags & CODE_GREEN);
  635.                         dobuffer(TRUE, 11);
  636.                 }   }
  637.                 elif
  638.                 (   !infomatched
  639.                  && (os[i].flags & INFO)
  640.                  && (stringholder1[length - 5] == '.')
  641.                 ) // we probably have a match, let's confirm
  642.                 {   strcpy(IOBuffer, os[i].pathname);
  643.                     strcat(IOBuffer, ".info");
  644.                     if (quickcomp(stringholder1, IOBuffer))
  645.                     {   // we have a match
  646.                         infomatched = os[i].infomatched = TRUE;
  647.  
  648.                         // check whether file is obsoleted by OS3.9 or by Genesis Update
  649.                         if
  650.                         (   (theversion >= 39 && (os[i].flags & NOT39))
  651.                          || (theversion >= 40 && (os[i].flags & NOT39UPDATE))
  652.                         )
  653.                         {   dobuffer(TRUE, 12); // obsolete
  654.                         } else
  655.                         {   dobuffer(TRUE, 11); // automatic .info files are always green
  656.         }   }   }   }   }
  657.         if (!matched && !infomatched) // third-party (cyan)
  658.         {   strcpy(IOBuffer, stringholder1);
  659.             dobuffer(TRUE, 13);
  660.     }   }
  661.  
  662.     // missing files
  663.     if (!stop)
  664.     {   for (i = 0; i <= FILES; i++)
  665.         {   if
  666.             (   !(os[i].flags & CODE_BLUE) // missing obsolete are NEVER shown
  667.              && (   (files.show[6] && !(os[i].flags & OPTIONAL))
  668.                  || (files.show[7] &&  (os[i].flags & OPTIONAL))
  669.                 )
  670.              && os[i].version <= theversion
  671.              && (theversion < 39 || !(os[i].flags & NOT39))
  672.              && (theversion < 40 || !(os[i].flags & NOT39UPDATE))
  673.             )
  674.             {   if (!os[i].matched)
  675.                 {   strcpy(IOBuffer, os[i].pathname); // white (missing)
  676.                     dobuffer(TRUE, 14);
  677.                 }
  678.                 if ((os[i].flags & INFO) && !os[i].infomatched)
  679.                 {   strcpy(IOBuffer, os[i].pathname); // white (missing)
  680.                     strcat(IOBuffer, ".info");
  681.                     dobuffer(TRUE, 14);
  682.     }   }   }   }
  683.  
  684.     if (shared.log && TheFileHandle)
  685.     {   Close(TheFileHandle); // Close() doesn't return an error code
  686.         TheFileHandle = NULL;
  687. }   }
  688.  
  689. MODULE void stage3(void)
  690. {   if (wbval >= 44)
  691.     {   /* pens go thusly:
  692.         0 red
  693.         1 orange
  694.         2 yellow
  695.         3 green
  696.         4 blue
  697.         5 cyan
  698.         6 white */
  699.  
  700.         GT_SetGadgetAttrs
  701.         (   TE101_Status,
  702.             MainWindowPtr, NULL,
  703.             GTTX_Text, "Ready",
  704.             TAG_DONE
  705.         );
  706.         GT_SetGadgetAttrs
  707.         (   BU99_Stop,
  708.             MainWindowPtr, NULL,
  709.             GA_Disabled, TRUE,
  710.             TAG_DONE
  711.         );
  712.  
  713.         SetGadgetAttrs
  714.         (   gadgets[GID_10_LB1], MainWindowPtr, NULL,
  715.             LISTBROWSER_Labels, NULL,
  716.             TAG_END
  717.         );
  718.         SetGadgetAttrs
  719.         (   gadgets[GID_10_LB1], MainWindowPtr, NULL,
  720.             LISTBROWSER_Labels, (ULONG) &ResultList,
  721.             TAG_END
  722.         );
  723. }   }
  724.  
  725. /* FileNamePtr[]: each of these is a pointer to the allocated memory
  726. area holding the pathname of that file found (excepting "SYS:" portion).
  727. FileNamesAllocated = number of elements of FileNamePtr[]. Or, another way
  728. to think of it, the number of files on the SYS: partition. Element 0 of
  729. the array is not used. */
  730.  
  731. MODULE void files_work(void)
  732. {   BOOL                 more; // BOOL, not ABOOL
  733.     BPTR                 DirHandle; // = NULL;
  734.     struct ExAllControl* eac;       // = NULL;
  735.     struct ExAllData*    ead;
  736.  
  737.     /* Service routine for stage1(). Each call of this routine
  738.     handles one directory from the work stack. This routine is the one
  739.     that actually makes the DOS calls. It pushes any subdirectories
  740.     found onto the stack.
  741.  
  742.     stringholder1 contains the pathname of the directory to examine
  743.         (without "SYS:").
  744.     lockstring contains the pathname of the directory to examine
  745.         (with "SYS:").
  746.     stringholder2 will contain the pathname of each file/dir found
  747.         (with "SYS:"). */
  748.  
  749.     strcpy(lockstring, "SYS:");
  750.     strcat(lockstring, stringholder1);
  751.  
  752.     if (!(DirHandle = (BPTR) Lock(lockstring, ACCESS_READ)))
  753.     {   // Printf("Can't lock %s!\n", lockstring);
  754.         rq("Can't lock directory!");
  755.     }
  756.     if (!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  757.     {   UnLock(DirHandle);
  758.         DirHandle = NULL;
  759.         rq("Can't allocate DOS object!");
  760.     }
  761.  
  762.     eac->eac_LastKey = 0;
  763.     do
  764.     {   more = ExAll(DirHandle, (struct ExAllData *) EADataPtr, 2048, ED_SIZE, eac);
  765.         if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  766.         {   FreeDosObject(DOS_EXALLCONTROL, eac);
  767.             eac = NULL;
  768.             UnLock(DirHandle);
  769.             DirHandle = NULL;
  770.             rq("Can't examine path!"); /* ExAll() failed abnormally */
  771.         }
  772.         if (eac->eac_Entries == 0)
  773.         {   ; /* ExAll() failed normally with no entries */
  774.             continue; /* more is USUALLY zero */
  775.         }
  776.         ead = (struct ExAllData *) EADataPtr;
  777.  
  778.         do
  779.         {   /* use ead here */
  780.  
  781.             strcpy(stringholder2, lockstring);
  782.             if (!AddPart(stringholder2, ead->ed_Name, VLONGFIELD))
  783.             {   FreeDosObject(DOS_EXALLCONTROL, eac);
  784.                 eac = NULL;
  785.                 UnLock(DirHandle);
  786.                 DirHandle = NULL;
  787.                 rq("Can't add filename/dirname to pathname!");
  788.             }
  789.             if (ead->ed_Type == 2) /* +2 is dir, +3 is softlink, -3 is file */
  790.             {   AddNameToTail(&DirList,  &(stringholder2[4]));
  791.             } elif (ead->ed_Type == -3) // if it's a file
  792.             {   AddNameToTail(&FileList, &(stringholder2[4]));
  793.             }
  794.  
  795.             /* get next ead */
  796.             ead = ead->ed_Next;
  797.         } while(ead);
  798.     } while(more);
  799.  
  800.     FreeDosObject(DOS_EXALLCONTROL, eac);
  801.     eac = NULL;
  802.     UnLock(DirHandle);
  803.     DirHandle = NULL;
  804. }
  805.  
  806. MODULE ABOOL __inline quickcomp(STRPTR first, STRPTR second)
  807. {   ULONG i = 0;
  808.  
  809.     while (*(first + i))
  810.     {   if (*(first + i)      != *(second + i)
  811.         &&  *(first + i)      != *(second + i) + 32
  812.         &&  *(first + i) + 32 != *(second + i)
  813.         &&  *(first + i) + 32 != *(second + i) + 32
  814.         )
  815.             return FALSE;
  816.         i++;
  817.     }
  818.     return TRUE;
  819. }
  820.  
  821. MODULE void dobuffer(ABOOL item, ULONG whichpen)
  822. {   struct Node* ListBrowserNodePtr;
  823.     TEXT         codestring[VLONGFIELD + 1];
  824.     ULONG        truewhichpen;
  825.  
  826.     /* Service routine for stage2(). */
  827.  
  828.     if (item && wbval >= 44 && files.show[whichpen - 8])
  829.     {   if (pal)
  830.         {   if (whichpen == 14)
  831.             {   truewhichpen = 2; // white
  832.             } else truewhichpen = whichpen;
  833.  
  834.             if (!(ListBrowserNodePtr = AllocListBrowserNode
  835.             (   1,              // columns,
  836.                 LBNA_Column,    0,
  837.                 LBNA_Flags,     LBFLG_CUSTOMPENS,
  838.                 LBNCA_FGPen,    BLACK,
  839.                 LBNCA_BGPen,    truewhichpen,
  840.                 LBNCA_CopyText, TRUE,
  841.                 LBNCA_Text,     IOBuffer,
  842.                 TAG_END))
  843.             )
  844.             {   rq("Can't create ReAction listbrowser.gadget node(s)!");
  845.         }   }
  846.         else
  847.         {   if (!(ListBrowserNodePtr = AllocListBrowserNode
  848.             (   1,              // columns,
  849.                 LBNA_Column,    0,
  850.                 LBNA_Flags,     LBFLG_CUSTOMPENS,
  851.                 LBNCA_FGPen,    BLACK,
  852.                 LBNCA_BGPen,    penn[whichpen - 8].pennumber,
  853.                 LBNCA_CopyText, TRUE,
  854.                 LBNCA_Text,     IOBuffer,
  855.                 TAG_END))
  856.             )
  857.             {   rq("Can't create ReAction listbrowser.gadget node(s)!");
  858.         }   }
  859.         AddTail(&ResultList, ListBrowserNodePtr); // AddTail() has no return code
  860.         list_has_nodes = TRUE;
  861.     }
  862.     if (shared.log)
  863.     {   if (item)
  864.         {   switch(whichpen)
  865.             {
  866.             case 8:
  867.                 strcpy(codestring, "! "); // red
  868.             break;
  869.             case 9:
  870.                 strcpy(codestring, "@ "); // orange
  871.             break;
  872.             case 10:
  873.                 strcpy(codestring, "# "); // yellow
  874.             break;
  875.             case 11:
  876.                 strcpy(codestring, "$ "); // green
  877.             break;
  878.             case 12:
  879.                 strcpy(codestring, "% "); // blue (obsolete)
  880.             break;
  881.             case 13:
  882.                 strcpy(codestring, "& "); // cyan (3rd-party)
  883.             break;
  884.             case 14:
  885.                 strcpy(codestring, "- "); // white (missing)
  886.             break;
  887.             default:
  888.                 // assert(0);
  889.             break;
  890.             }
  891.             strcat(codestring, IOBuffer);
  892.         } else
  893.         {   strcpy(codestring, IOBuffer);
  894.         }
  895.         strcat(codestring, "\n");
  896.         if (Write(TheFileHandle, codestring, strlen(codestring)) == -1)
  897.         {   rq("Can't append to file!");
  898. }   }   }
  899.  
  900. AGLOBAL void files_loop(ULONG class, struct Gadget* addr, UWORD code, UWORD qual)
  901. {   ULONG i, scroll;
  902.  
  903.     if (class == IDCMP_RAWKEY && wbval >= 44)
  904.     {   if (code == SCAN_UP)
  905.         {   if (qual & IEQUALIFIER_CONTROL)
  906.             {   scroll = LBP_TOP;
  907.             } elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
  908.             {   scroll = LBP_PAGEUP;
  909.             } else scroll = LBP_LINEUP;
  910.         } elif (code == SCAN_DOWN)
  911.         {   if (qual & IEQUALIFIER_CONTROL)
  912.             {   scroll = LBP_BOTTOM;
  913.             } elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
  914.             {   scroll = LBP_PAGEDOWN;
  915.             } else scroll = LBP_LINEDOWN;
  916.         }
  917.         if (code == SCAN_UP || code == SCAN_DOWN)
  918.         {   SetGadgetAttrs
  919.             (   gadgets[GID_10_LB1],          // pointer to gadget
  920.                 MainWindowPtr,                // pointer to window (not window object!)
  921.                 NULL,                         // pointer to requester
  922.                 LISTBROWSER_Position, scroll, // tags
  923.                 TAG_DONE                      // done
  924.             );
  925.     }   }
  926.     elif (class == IDCMP_VANILLAKEY)
  927.     {   code = toupper(code);
  928.         if (code == 'V')
  929.         {   if (!(qual & IEQUALIFIER_LSHIFT) && !(qual & IEQUALIFIER_RSHIFT))
  930.             {   if (osversion < OSVERSIONS)
  931.                     osversion++;
  932.                 else osversion = 0;
  933.             } else
  934.             {   if (osversion > 0)
  935.                     osversion--;
  936.                 else osversion = OSVERSIONS;
  937.             }
  938.             GT_SetGadgetAttrs
  939.             (   CY101_OSVersion,
  940.                 MainWindowPtr,
  941.                 NULL,
  942.                 GTMX_Active, osversion,
  943.                 TAG_DONE
  944.             );
  945.         } elif (code == 'L')
  946.         {   fliplog(TRUE);
  947.         } elif (code == 'U')
  948.         {   updatefiles();
  949.         } elif (code == 'E')
  950.         {   if (CB101_Show[0]->Flags & GFLG_SELECTED)
  951.                 files.show[0] = FALSE;
  952.             else files.show[0] = TRUE;
  953.             GT_SetGadgetAttrs
  954.             (   CB101_Show[0],
  955.                 MainWindowPtr, NULL,
  956.                 GTCB_Checked, files.show[0],
  957.                 TAG_DONE
  958.             );
  959.         } elif (code == 'I')
  960.         {   if (CB101_Show[1]->Flags & GFLG_SELECTED)
  961.                 files.show[1] = FALSE;
  962.             else files.show[1] = TRUE;
  963.             GT_SetGadgetAttrs
  964.             (   CB101_Show[1],
  965.                 MainWindowPtr, NULL,
  966.                 GTCB_Checked, files.show[1],
  967.                 TAG_DONE
  968.             );
  969.         } elif (code == 'S')
  970.         {   if (CB101_Show[2]->Flags & GFLG_SELECTED)
  971.                 files.show[2] = FALSE;
  972.             else files.show[2] = TRUE;
  973.             GT_SetGadgetAttrs
  974.             (   CB101_Show[2],
  975.                 MainWindowPtr, NULL,
  976.                 GTCB_Checked, files.show[2],
  977.                 TAG_DONE
  978.             );
  979.         } elif (code == 'N')
  980.         {   if (CB101_Show[3]->Flags & GFLG_SELECTED)
  981.                 files.show[3] = FALSE;
  982.             else files.show[3] = TRUE;
  983.             GT_SetGadgetAttrs
  984.             (   CB101_Show[3],
  985.                 MainWindowPtr, NULL,
  986.                 GTCB_Checked, files.show[3],
  987.                 TAG_DONE
  988.             );
  989.         } elif (code == 'B')
  990.         {   if (CB101_Show[4]->Flags & GFLG_SELECTED)
  991.                 files.show[4] = FALSE;
  992.             else files.show[4] = TRUE;
  993.             GT_SetGadgetAttrs
  994.             (   CB101_Show[4],
  995.                 MainWindowPtr, NULL,
  996.                 GTCB_Checked, files.show[4],
  997.                 TAG_DONE
  998.             );
  999.         } elif (code == '3')
  1000.         {   if (CB101_Show[5]->Flags & GFLG_SELECTED)
  1001.                 files.show[5] = FALSE;
  1002.             else files.show[5] = TRUE;
  1003.             GT_SetGadgetAttrs
  1004.             (   CB101_Show[5],
  1005.                 MainWindowPtr, NULL,
  1006.                 GTCB_Checked, files.show[5],
  1007.                 TAG_DONE
  1008.             );
  1009.         } elif (code == 'G')
  1010.         {   if (CB101_Show[6]->Flags & GFLG_SELECTED)
  1011.                 files.show[6] = FALSE;
  1012.             else files.show[6] = TRUE;
  1013.             GT_SetGadgetAttrs
  1014.             (   CB101_Show[6],
  1015.                 MainWindowPtr, NULL,
  1016.                 GTCB_Checked, files.show[6],
  1017.                 TAG_DONE
  1018.             );
  1019.         } elif (code == 'P')
  1020.         {   if (CB101_Show[7]->Flags & GFLG_SELECTED)
  1021.                 files.show[7] = FALSE;
  1022.             else files.show[7] = TRUE;
  1023.             GT_SetGadgetAttrs
  1024.             (   CB101_Show[7],
  1025.                 MainWindowPtr, NULL,
  1026.                 GTCB_Checked, files.show[7],
  1027.                 TAG_DONE
  1028.             );
  1029.         } elif (code == 'O')
  1030.         {   ActivateGadget(ST99_Output, MainWindowPtr, NULL);
  1031.         } elif (code == '.')
  1032.         {   if (asl())
  1033.             {   GT_SetGadgetAttrs
  1034.                 (   ST99_Output,
  1035.                     MainWindowPtr,
  1036.                     NULL,
  1037.                     GTST_String, aslresult,
  1038.                     TAG_DONE
  1039.                 );
  1040.         }   }
  1041.         elif (code == ESCAPE)
  1042.         {   page = 0;
  1043.     }   }
  1044.     elif (class == IDCMP_GADGETUP)
  1045.     {   /* IDCMP_GADGETUP is sent by the string gadget
  1046.            when the user presses RETURN, ENTER, Help, Tab
  1047.            or Shift-Tab inside the string gadget. */
  1048.  
  1049.         if (addr == BU99_Right)
  1050.         {   page = 0;
  1051.         } elif (addr == BU99_Update)
  1052.         {   updatefiles();
  1053.         } elif (addr == CB99_Log)
  1054.         {   fliplog(FALSE);
  1055.         } elif (addr == ST99_Output)
  1056.         {   outputstring();
  1057.         } elif (addr == BU99_OutputASL)
  1058.         {   outputasl();
  1059.         } elif (addr == CY101_OSVersion)
  1060.         {   osversion = code;
  1061.         } else
  1062.         {   for (i = 0; i <= 6; i++)
  1063.             {   if (addr == CB101_Show[i])
  1064.                 {   if (CB101_Show[i]->Flags & GFLG_SELECTED)
  1065.                     {   files.show[i] = TRUE;
  1066.                     } else files.show[i] = FALSE;
  1067.                     GT_SetGadgetAttrs
  1068.                     (   CB101_Show[i],
  1069.                         MainWindowPtr, NULL,
  1070.                         GTCB_Checked, files.show[i],
  1071.                         TAG_DONE
  1072.                     );
  1073.                     break;
  1074. }   }   }   }   }
  1075.  
  1076. AGLOBAL void files_init(void)
  1077. {   ULONG i;
  1078.  
  1079.     if (wbval <= 43)
  1080.     {   osversion = 0;  // OS3.1
  1081.     } elif (wbval == 44)
  1082.     {   osversion = 2;  // OS3.5 + BB1/2
  1083.     } else osversion = 5; // OS3.9 + BB1
  1084.  
  1085.     NewList(&EmptyList);
  1086.  
  1087.     if (!pal)
  1088.     {   if (!(ScreenPtr = LockPubScreen(NULL)))
  1089.             rq("Can't lock default public screen!");
  1090.         for (i = 0; i <= 6; i++)
  1091.         {   penn[i].pennumber = FindColor
  1092.             (   ScreenPtr->ViewPort.ColorMap,
  1093.                 penn[i].red,
  1094.                 penn[i].green,
  1095.                 penn[i].blue,
  1096.                 -1
  1097.             );
  1098.         }
  1099.         UnlockPubScreen(NULL, ScreenPtr);
  1100.         for (i = 0; i <= 6; i++)
  1101.         {   penn[i].pennumber = FindColor
  1102.             (   ScreenPtr->ViewPort.ColorMap,
  1103.                 penn[i].red,
  1104.                 penn[i].green,
  1105.                 penn[i].blue,
  1106.                 -1
  1107.             );
  1108. }   }   }
  1109.  
  1110. AGLOBAL void files_exit(void)
  1111. {   // The window should be closed before calling this.
  1112.  
  1113.     if (shared.log && TheFileHandle)
  1114.     {   Close(TheFileHandle); // Close() doesn't return an error code
  1115.         TheFileHandle = NULL;
  1116. }   }
  1117.  
  1118. // Function to free an Exec List of ListBrowser nodes.
  1119. AGLOBAL void clearlblist(void)
  1120. {   /* Requirements: listbrowser class must be already open, and list
  1121.     must be detached from gadget*/
  1122.  
  1123.     struct Node *NodePtr, *NextNodePtr;
  1124.  
  1125.     if (wbval >= 44)
  1126.     {   if (list_has_nodes)
  1127.         {   NodePtr = ResultList.lh_Head;
  1128.             while (NextNodePtr = NodePtr->ln_Succ)
  1129.             {   FreeListBrowserNode(NodePtr);
  1130.                 NodePtr = NextNodePtr;
  1131.         }   }
  1132.         list_has_nodes = FALSE;
  1133.         NewList(&ResultList);
  1134. }   }
  1135.